#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/prctl.h>

#define PR_SET_TAGGED_ADDR_CTRL		55
#define PR_TAGGED_ADDR_ENABLE		(1UL << 0)

#define TAG_SHIFT			56

int main(void)
{
	int tbi_enabled = 0;
	unsigned long tag = 0;
	char *ptr;

	/* check/enable the tagged address ABI */
	//if (!prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0))
		tbi_enabled = 1;

	/* memory allocation */
	ptr = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	if (ptr == MAP_FAILED)
		return 1;

	/* set a non-zero tag if the ABI is available */
	if (tbi_enabled) {
		printf("tbi enabled\n");
		tag = 0xaa;
	}

	ptr = (char *)((unsigned long)ptr | (tag << TAG_SHIFT));

	/* memory access to a tagged address */
	strcpy(ptr, "tagged pointer\n");

	/* syscall with a tagged pointer */
	write(1, ptr, strlen(ptr));
	printf("ptr=%p\n", ptr);
	printf("ptr=%s\n", ptr);


	return 0;
}
